package com.example.OnlineStorage.service.Download;

import com.example.OnlineStorage.Dao.FileSHA256Dao;
import com.example.OnlineStorage.Dao.ShareFilePermissionsDao;
import com.example.OnlineStorage.Dao.ShareFilesDao;
import com.example.OnlineStorage.enums.GlobalVariables_String;
import com.example.OnlineStorage.exception.CustomException;
import com.example.OnlineStorage.pojo.Response.ResponseData;
import com.example.OnlineStorage.pojo.entity.Node;
import com.example.OnlineStorage.pojo.entity.ShareFilePermissions;
import com.example.OnlineStorage.pojo.entity.ShareFiles;
import com.example.OnlineStorage.pojo.entity.User;
import com.example.OnlineStorage.util.IO;
import com.example.OnlineStorage.util.PermissionsControl;
import com.example.OnlineStorage.util.Redis;
import lombok.SneakyThrows;
import org.springframework.stereotype.Service;

@Service
public class IDownloadService implements DownloadService {


    private final ShareFilesDao shareFilesDao;
    private final ShareFilePermissionsDao shareFilePermissionsDao;

    private final FileSHA256Dao fileSha256Dao;

    public IDownloadService(ShareFilesDao shareFilesDao,
                            ShareFilePermissionsDao shareFilePermissionsDao,
                            FileSHA256Dao fileSHA256Dao
    ) {
        this.shareFilesDao = shareFilesDao;
        this.shareFilePermissionsDao = shareFilePermissionsDao;
        this.fileSha256Dao = fileSHA256Dao;
    }

    @SneakyThrows
    @Override
    public ResponseData Download(String address, String name, String range, String UUID) {
        try {
            User user = User.fromJson(Redis.HGET(Redis.GET(UUID), "user"));
            Node root = Node.fromJson(user.getFileDataJson());
            if (!root.isFileSHA_256Exist(address)) {
                throw new RuntimeException("没有该资源");
            }
            long start = 0;
            if (range != null) {
                start = Long.parseLong(range.split("=")[1].split("-")[0]);
            }
            String Path = GlobalVariables_String.File_Path_Files.getValue() + address;
            return IO.DownloadFile(Path, name, start, range);

        } catch (Exception e) {
            if (e.getCause() != null) {
                String Cause = e.getCause().toString();
                if (Cause.startsWith("java.sql.SQL")) {
                    throw new CustomException(500, "服务器异常.请联系管理员.");
                }
            }
            throw new CustomException(400, e.getMessage());
        }
    }

    @SneakyThrows
    @Override
    public ResponseData Download(Long shareFilesId, String address, String name, String range, String UUID) {
        try {
            User user = User.fromJson(Redis.HGET(Redis.GET(UUID), "user"));
            ShareFilePermissions sfp = new ShareFilePermissions();
            sfp.setShareFilesId(shareFilesId);
            sfp.setUserId(user.getId());
            Long shareFilesPermissionId = shareFilePermissionsDao.select(sfp);
            if (!PermissionsControl.isDownload(shareFilesPermissionId)) {
                throw new RuntimeException("没有下载权限");
            }
            ShareFiles shareFiles = shareFilesDao.select(shareFilesId);
            if (shareFiles == null) {
                throw new RuntimeException("该共享文件夹不存在");
            }
            Node root = Node.fromJson(shareFiles.getFileDataJson());
            if (!root.isFileSHA_256Exist(address)) {
                throw new RuntimeException("没有该资源");
            }
            long start = 0;
            if (range != null) {
                start = Long.parseLong(range.split("=")[1].split("-")[0]);
            }
            String Path = GlobalVariables_String.File_Path_Files.getValue() + address;
            return IO.DownloadFile(Path, name, start, range);
        } catch (Exception e) {
            if (e.getCause() != null) {
                String Cause = e.getCause().toString();
                if (Cause.startsWith("java.sql.SQL")) {
                    throw new CustomException(500, "服务器异常.请联系管理员.");
                }
            }
            throw new CustomException(400, e.getMessage());
        }
    }

    @SneakyThrows
    @Override
    public ResponseData DownloadByPath(String path, String name, String range, String UUID) {
        try {
            User user = User.fromJson(Redis.HGET(Redis.GET(UUID), "user"));
            Node root = Node.fromJson(user.getFileDataJson());
            Node node = root.getChildByPath(path);
            if (node == null) {
                throw new RuntimeException("没有该资源.");
            }
            String SHA_256 = node.getSHA_256();
            long start = 0;
            if (range != null) {
                start = Long.parseLong(range.split("=")[1].split("-")[0]);
            }
            String Path = GlobalVariables_String.File_Path_Files.getValue() + SHA_256;
            return IO.DownloadFile(Path, name, start, range);
        } catch (Exception e) {
            if (e.getCause() != null) {
                String Cause = e.getCause().toString();
                if (Cause.startsWith("java.sql.SQL")) {
                    throw new CustomException(500, "服务器异常.请联系管理员.");
                }
            }
            throw new CustomException(400, e.getMessage());
        }
    }

    @SneakyThrows
    @Override
    public ResponseData DownloadByPath(Long shareFilesId, String path, String name, String range, String UUID) {
        try {
            User user = User.fromJson(Redis.HGET(Redis.GET(UUID), "user"));
            ShareFilePermissions sfp = new ShareFilePermissions();
            sfp.setShareFilesId(shareFilesId);
            sfp.setUserId(user.getId());
            Long shareFilesPermissionId = shareFilePermissionsDao.select(sfp);
            if (!PermissionsControl.isDownload(shareFilesPermissionId)) {
                throw new RuntimeException("没有下载权限");
            }
            ShareFiles shareFiles = shareFilesDao.select(shareFilesId);
            if (shareFiles == null) {
                throw new RuntimeException("该共享文件夹不存在");
            }
            Node root = Node.fromJson(shareFiles.getFileDataJson());
            Node node = root.getChildByPath(path);
            if (node == null) {
                throw new RuntimeException("没有该资源.");
            }
            String SHA_256 = node.getSHA_256();
            long start = 0;
            if (range != null) {
                start = Long.parseLong(range.split("=")[1].split("-")[0]);
            }
            String Path = GlobalVariables_String.File_Path_Files.getValue() + SHA_256;
            return IO.DownloadFile(Path, name, start, range);
        } catch (Exception e) {
            if (e.getCause() != null) {
                String Cause = e.getCause().toString();
                if (Cause.startsWith("java.sql.SQL")) {
                    throw new CustomException(500, "服务器异常.请联系管理员.");
                }
            }
            throw new CustomException(400, e.getMessage());
        }
    }

    @SneakyThrows
    @Override
    public ResponseData OnlinePreviewByPath( String path, String range, String UUID) {
        try {
            User user = User.fromJson(Redis.HGET(Redis.GET(UUID), "user"));
            Node root = Node.fromJson(user.getFileDataJson());
            Node node = root.getChildByPath(path);
            if (node == null) {
                //这里不能抛出错误，要返回 404 的图片
                return IO.onlineReadFile(GlobalVariables_String.File_Path_Files.getValue() + GlobalVariables_String.Not.getValue(), 0, null);
            }
            String SHA_256 = node.getSHA_256();
            long start = 0;
            if (range != null) {
                start = Long.parseLong(range.split("=")[1].split("-")[0]);
            }
            String Path = GlobalVariables_String.File_Path_Files.getValue() + SHA_256;
            return IO.onlineReadFile(Path, start, range);
        } catch (Exception e) {
            if (e.getCause() != null) {
                String Cause = e.getCause().toString();
                if (Cause.startsWith("java.sql.SQL")) {
                    throw new CustomException(500, "服务器异常.请联系管理员.");
                }
            }
            throw new CustomException(400, e.getMessage());
        }
    }
    @SneakyThrows
    @Override
    public ResponseData OnlinePreviewByPath(Long shareFilesId, String path, String range, String UUID) {
        try {
            User user = User.fromJson(Redis.HGET(Redis.GET(UUID), "user"));
            ShareFiles shareFiles = shareFilesDao.select(shareFilesId);
            if (shareFiles == null) {
                //这里不能抛出错误，要返回 404 的图片
                return IO.onlineReadFile(GlobalVariables_String.File_Path_Files.getValue() + GlobalVariables_String.Not.getValue(), 0, null);
            }
            Node root = Node.fromJson(shareFiles.getFileDataJson());
            Node node = root.getChildByPath(path);
            if (node == null) {
                //这里不能抛出错误，要返回 404 的图片
                return IO.onlineReadFile(GlobalVariables_String.File_Path_Files.getValue() + GlobalVariables_String.Not.getValue(), 0, null);
            }
            String SHA_256 = node.getSHA_256();
            long start = 0;
            if (range != null) {
                start = Long.parseLong(range.split("=")[1].split("-")[0]);
            }
            String Path = GlobalVariables_String.File_Path_Files.getValue() + SHA_256;
            return IO.onlineReadFile(Path, start, range);
        } catch (Exception e) {
            if (e.getCause() != null) {
                String Cause = e.getCause().toString();
                if (Cause.startsWith("java.sql.SQL")) {
                    throw new CustomException(500, "服务器异常.请联系管理员.");
                }
            }
            throw new CustomException(400, e.getMessage());
        }
    }

}
